﻿using System;
using System.Collections.Generic;
using Microsoft.SharePoint;
using Kiiro.Common.Entities;
using Kiiro.Common.Utility;
using Kiiro.DataAccess;
using Kiiro.ExceptionManagement;
using Kiiro.Validation.Validators.Entities;

namespace Kiiro.Model
{
    public class DiscussionModel
    {
        public static Discussion GetById ( int discussionId, Guid siteCollectionId, string serverRelativeUrl )
        {
            Discussion discussion = null;
            List<Discussion> discussions = GetDiscussionsByIds( new List<int>( ) { discussionId }, siteCollectionId, serverRelativeUrl );

            if ( discussions.Count > 0 )
                discussion = discussions[0];

            return discussion;
        }
         
        /// <summary>
        /// Gets a list of Discussion entities. If discussionIds is null or empty this method returns ALL Discussions.
        /// </summary>
        /// <param name="discussionIds">The list of discussion ids to get. If discussionIds is null or empty this method returns ALL discussions.</param>
        /// <param name="siteCollectionId">The site collection id</param>
        /// <param name="serverRelativeUrl">The server relative url</param>
        /// <returns>If discussionIds is null or empty this method returns ALL discussions.</returns>
        public static List<Discussion> GetDiscussionsByIds ( List<int> discussionIds, Guid siteCollectionId, string serverRelativeUrl )
        {
            List<Discussion> discussions = DiscussionDA.Instance.GetDiscussionsByIds ( discussionIds, siteCollectionId, serverRelativeUrl );

            if ( discussions.Count > 0 )
            {
                // TODO: GetTeamMembers won't return TeamMembers for deleted Users
                List<TeamMember> members = TeamModel.GetTeamMembers ( siteCollectionId, serverRelativeUrl );
                TeamMember member = null;

                // re-link CreatedBy and ModifiedBy properties
                foreach ( Discussion discussion in discussions )
                {
                    if ( discussion.CreatedBy != null && discussion.CreatedBy.Id != default ( int ) )
                    {
                        member = members.Find ( m => m.UserId == discussion.CreatedBy.Id );
                        if ( member != null )
                        {
                            discussion.CreatedBy = member.User;
                        }
                    }

                    if ( discussion.ModifiedBy != null && discussion.ModifiedBy.Id != default ( int ) )
                    {
                        member = members.Find ( m => m.UserId == discussion.ModifiedBy.Id );
                        if ( member != null )
                        {
                            discussion.ModifiedBy = member.User;
                        }
                    }

                    if ( discussion.Comments.Count > 0 )
                    {
                        // re-link CreatedBy and ModifiedBy properties
                        foreach ( Comment comment in discussion.Comments )
                        {
                            if ( comment.CreatedBy != null && comment.CreatedBy.Id != default ( int ) )
                            {
                                member = members.Find ( m => m.UserId == comment.CreatedBy.Id );
                                if ( member != null )
                                {
                                    comment.CreatedBy = member.User;
                                }
                            }

                            if ( comment.ModifiedBy != null && comment.ModifiedBy.Id != default ( int ) )
                            {
                                member = members.Find ( m => m.UserId == comment.CreatedBy.Id );
                                if ( member != null )
                                {
                                    comment.CreatedBy = member.User;
                                }
                            }
                        }
                    }
                }
            }

            return discussions;
        }

        public static List<Discussion> GetRecentDiscussions ( Guid siteCollectionId, string serverRelativeUrl )
        {
            return DiscussionDA.Instance.GetRecentDiscussions ( siteCollectionId, serverRelativeUrl );
        }

        public static Discussion Save ( Discussion discussion, Guid siteCollectionId, string serverRelativeUrl )
        {
            Midori midori = new Midori();
            midori.Discussions.Add(discussion);
            midori = Save(midori, siteCollectionId, serverRelativeUrl);

            if (midori.Discussions.Count > 0)
                discussion = midori.Discussions[0];
            
            return discussion;
        }

        public static Midori Save(Midori midori, Guid siteCollectionId, string serverRelativeUrl)
        {
            try
            {
                foreach (Discussion discussion in midori.Discussions)
                {
                    if (discussion != null && discussion.EditType != EditType.Unchanged)
                    {
                        PermissionsModel.GetGlobalPermissionBitsForCurrentUser ( discussion, discussion.ModifiedBy, siteCollectionId, serverRelativeUrl, false );

                        if (discussion.PermissionBitsDiscussions != null && discussion.PermissionBitsDiscussions.Count > 0 &&
                            (discussion.PermissionBitsDiscussions[0] || discussion.PermissionBitsDiscussions[2] || discussion.PermissionBitsDiscussions[3]))
                        {
                            
                            new DiscussionValidator().Validate(discussion);

                            if (discussion.EditType == EditType.Deleted || discussion.IsValid())
                            {
                                bool sendEmail = discussion.EditType == EditType.Created;
                                List<int> usersToNotify = discussion.UsersToNotify;

                                List<Attachment> attachments = discussion.AttachmentList;

                                DiscussionDA.Instance.Save(discussion, siteCollectionId, serverRelativeUrl);

                                discussion.AttachmentList = attachments;
                                if (discussion.EditType != EditType.Deleted)
                                    AttachmentModel.SaveAttachments(discussion, siteCollectionId, serverRelativeUrl);

                                if (sendEmail && usersToNotify.Count > 0)
                                {
                                    discussion.UsersToNotify = usersToNotify;
                                    EmailModel.Instance.SendDiscussionCreatedEmail(discussion, siteCollectionId, serverRelativeUrl, discussion.ModifiedBy);
                                }

                                ProjectsModel.UpdateProjectStatistics(midori, siteCollectionId, serverRelativeUrl);
                            }
                        }
                        else
                            throw new KiiroUnauthorizedAccessException ( "Updating Discussion Failed: Access Denied." );
                    }

                }
            }
            catch (Exception ex)
            {
                ExceptionManager.HandleException(ex, true);
            }

            return midori;
        }
    }
}

/*************************************************************************
 * 
 * $Log: /Internal Projects/Kiiro/Kiiro.Model/DiscussionModel.cs $
 * 
 * 17    2/08/10 5:04p Camerons
 * 
 * 16    1/25/10 1:17p Camerons
 * 
 * 15    1/12/10 12:03p Camerons
 * 
 * 14    26/11/09 10:35a Camerons
 * 
 * 13    17/11/09 6:46p Camerons
 * 
 * 12    22/09/09 6:03p Camerons
 * Code changes to support creating user on demand - version 1.1.x.x
 * 
 * 11    17/08/09 10:29a Camerons
 * Added check-in comments section
 * 
 ************************************************************************/